package org.springblade.modules.platform.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springblade.modules.platform.dto.PhysicalDataTableListByPageDTO;
import org.springblade.modules.platform.entity.MeasuringPointTable;
import org.springblade.modules.platform.mapper.EngineerValueTableMapper;
import org.springblade.modules.platform.mapper.MeasuringPointTableMapper;
import org.springblade.modules.platform.mapper.PhysicalValueTableMapper;
import org.springblade.modules.platform.service.IMeasuringPointTableService;

import org.springblade.modules.platform.utils.TimeUtils;
import org.springblade.modules.platform.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author SYG
 * @since 2022-11-29
 */
@Service
public class MeasuringPointTableServiceImpl extends ServiceImpl<MeasuringPointTableMapper, MeasuringPointTable> implements IMeasuringPointTableService {

    @Autowired
    PhysicalValueTableMapper physicalValueTableMapper;

    @Autowired
    EngineerValueTableMapper engineerValueTableMapper;

    @Override
    public MeasuringPointTableByPageVO getListByPage(PhysicalDataTableListByPageDTO rawDataTableListByPageDTO) {
        MeasuringPointTableByPageVO measuringPointTableByPageVO = new MeasuringPointTableByPageVO();
        QueryWrapper<MeasuringPointTable> queryWrapper = new QueryWrapper<>();

        if(rawDataTableListByPageDTO.getEndTime()!=null&&rawDataTableListByPageDTO.getStartTime()!=null){
            queryWrapper.lambda().ge(MeasuringPointTable::getGatherTime,rawDataTableListByPageDTO.getStartTime()).le(MeasuringPointTable::getGatherTime,rawDataTableListByPageDTO.getEndTime());
        }
        if(rawDataTableListByPageDTO.getGatherEvent()!=null){
            queryWrapper.lambda().eq(MeasuringPointTable::getGatherEvent,rawDataTableListByPageDTO.getGatherEvent());
        }
        if(rawDataTableListByPageDTO.getMeasurChain()!=null){
            queryWrapper.lambda().like(MeasuringPointTable::getMeasurChain,rawDataTableListByPageDTO.getMeasurChain());
        }

       queryWrapper.lambda().orderByDesc(MeasuringPointTable::getGatherTime);
        Page<MeasuringPointTable> rawDataTablePage = baseMapper.selectPage(new Page<>(rawDataTableListByPageDTO.getCurrent(), rawDataTableListByPageDTO.getSize()), queryWrapper);
        measuringPointTableByPageVO.setTotal(rawDataTablePage.getTotal());
        if(rawDataTablePage.getTotal()>0){
            List<MeasuringPointTable> records = rawDataTablePage.getRecords();
            List<MeasuringPointTableVO> collect = records.stream().map(x -> {
                MeasuringPointTableVO measuringPointTableVO = new MeasuringPointTableVO();
                BeanUtils.copyProperties(x, measuringPointTableVO);
                measuringPointTableVO.setGatherEvent(x.getGatherEvent()==2?"手动采集"+x.getAcquisitionFlag():"定时采集");
                return measuringPointTableVO;
            }).collect(Collectors.toList());

            measuringPointTableByPageVO.setList(collect.stream().sorted(Comparator.comparing(MeasuringPointTableVO::getId)).collect(Collectors.toList()));
        }
        return measuringPointTableByPageVO;
    }

    @Override
    public List<MeasuringPointTable> selectByTime(List<Long> list) {
        return baseMapper.selectList(Wrappers.<MeasuringPointTable>query().lambda().in(MeasuringPointTable::getGatherTime,list));
    }

    @Override
    public List<MeasuringPointTable> selectByTime(Long startDate, Long endDate) {
        return baseMapper.selectList(Wrappers.<MeasuringPointTable>query().lambda()
                .between(MeasuringPointTable::getGatherTime,startDate,endDate).groupBy(MeasuringPointTable::getGatherTime));
    }

    @Override
    public List<DataDetailsVO.MeasuringPointTableVO> selectListByDeptId(Long deptId, Long gatherTime,Integer measurChainDirection) {
        List<MeasuringPointTable> measuringPointTables = baseMapper.selectList(Wrappers.<MeasuringPointTable>query().lambda()
                .eq(MeasuringPointTable::getGatherTime, gatherTime)
                .eq(MeasuringPointTable::getMeasurChainDirection, measurChainDirection)
                .eq(MeasuringPointTable::getDeptId, deptId)
		.orderByAsc(MeasuringPointTable::getId));
        if(!CollectionUtils.isEmpty(measuringPointTables)){


            List<DataDetailsVO.MeasuringPointTableVO> collect = measuringPointTables.stream()
                  /*  .sorted(Comparator.comparing(MeasuringPointTable::getInsertTime).reversed())*/.map(x -> {
                DataDetailsVO.MeasuringPointTableVO measuringPointTableVO = new DataDetailsVO.MeasuringPointTableVO();
                BeanUtils.copyProperties(x,measuringPointTableVO);
                measuringPointTableVO.setOnceValue(Double.valueOf(x.getOnceValue()));
                return measuringPointTableVO;
            }).collect(Collectors.toList());
            return collect;
        }


        return null;
    }

    @Override
    public DeviceDetailsDTO getDeviceChart(String deviceId,Integer measurChainDirection, Long startDate, Long endDate) {
        DeviceDetailsDTO deviceDetailsDTO = new DeviceDetailsDTO();
        QueryWrapper<MeasuringPointTable> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(MeasuringPointTable::getDeviceId,deviceId);
        if(measurChainDirection!=null){
            queryWrapper.lambda().eq(MeasuringPointTable::getMeasurChainDirection,measurChainDirection);
        }
        List<MeasuringPointTable> measuringPointTables;
        if(startDate!=null&endDate!=null){
            measuringPointTables = baseMapper.selectList(Wrappers.<MeasuringPointTable>query().lambda()
                    .between(MeasuringPointTable::getGatherTime,startDate,endDate).eq(MeasuringPointTable::getDeviceId,deviceId)
                    .orderByDesc(MeasuringPointTable::getGatherTime));
        }else {
            Date date = TimeUtils.currentMax(new Date());
            Date date1 =  TimeUtils.localDateTime2Date(TimeUtils.localDateTimeSubtractionDay(TimeUtils.date2LocalDateTime(new Date()),100));
            List<MeasuringPointTable> engineerValueTables = baseMapper.selectList(Wrappers.<MeasuringPointTable>query().select("gather_time").lambda()
                    .groupBy(MeasuringPointTable::getGatherTime)
                    .orderByDesc(MeasuringPointTable::getGatherTime).between(MeasuringPointTable::getGatherTime,date1.getTime(),date.getTime()));
            if(!CollectionUtils.isEmpty(engineerValueTables)){
                List<Long> collect = engineerValueTables.stream().map(MeasuringPointTable::getGatherTime).collect(Collectors.toList());
                queryWrapper.lambda().in(MeasuringPointTable::getGatherTime,collect);
            }
            measuringPointTables = baseMapper.selectList(queryWrapper);
        }
        if(!CollectionUtils.isEmpty(measuringPointTables)){
            List<String> collect2 = measuringPointTables.stream().map(MeasuringPointTable::getPropertieId).distinct().collect(Collectors.toList());
            Map<String, List<MeasuringPointTable>> collect = measuringPointTables.stream().collect(
                    Collectors.groupingBy(MeasuringPointTable::getPropertieId, Collectors.toList()));
            List<DeviceDetailsDTO.AttributeVO> attributeVOList = new ArrayList<>();
            for (String s : collect2) {
                DeviceDetailsDTO.AttributeVO attributeVO = new DeviceDetailsDTO.AttributeVO();
                attributeVO.setPropertieId(s);
				if(s.equalsIgnoreCase("temperature")){
					attributeVO.setCompany("℃");
				}else if(s.equalsIgnoreCase("electricity")){
					attributeVO.setCompany("mA");
				}else{
					attributeVO.setCompany("像元");
				}
                List<MeasuringPointTable> measuringPointTables1 = collect.get(s);
                List<DeviceDetailsDTO.AttributeVO.DeviceVO> collect1 = measuringPointTables1.stream().map(l -> {
                    DeviceDetailsDTO.AttributeVO.DeviceVO deviceVO = new DeviceDetailsDTO.AttributeVO.DeviceVO();
                    deviceVO.setValue(l.getOnceValue()+"");
                    deviceVO.setTimes(l.getGatherTime());
                    attributeVO.setPropertieName(l.getPropertieName());
                    deviceVO.setGatherTime(TimeUtils.timeStampConversionTime(l.getGatherTime(), "yyyy-MM-dd HH:mm:ss"));
                    return deviceVO;
                }).sorted(Comparator.comparing(DeviceDetailsDTO.AttributeVO.DeviceVO::getTimes)).collect(Collectors.toList());
                attributeVO.setDeviceVOS(collect1);
                attributeVOList.add(attributeVO);
            }

            deviceDetailsDTO.setAttributeVOList(attributeVOList);
        }
        return deviceDetailsDTO;
    }
}
